import $ from "jquery";
import System from "./system";
import EventCenter from "./event_center";
import AssetItem from "./asset_item";
import ProgressEvent from "./progress_event";
import Event from "./event";
import ErrorEvent from "./error_event";
import UrlUtil from "./url_util";
import AssetTypes from "./asset_types";

export default class AssetsLoader {
  constructor(e?) {
    let t = this;
    isNaN(e) === !1 && (t._threadsCount = e)
  }
  static _assets = null;
  static assets() {
    return this._assets == null && (this._assets = {}), this._assets;
  }
  static threadsCount = 10;
  static asset(e) {
    let t = this.assets(),
      n = t[e];
    return n != null ? n.asset : null;
  }
  static releaseAssets(e) {
    let t = this.assets();
    for (let n = 0; n < e.length; n++) {
      let r = e[n],
        i = UrlUtil.splitURLs(r);
      for (let s = 0; s < i.length; s++) {
        let o = i[s];
        if (t.hasOwnProperty(o)) {
          let a = t[o];
          (a.referenceCount -= 1), a.referenceCount <= 0 && delete t[o];
        }
      }
    }
  }
  static releaseAll() {
    let e = this.assets();
    for (let t in e)
      if (e.hasOwnProperty(t)) {
        let n = e[t];
        (n.referenceCount -= 1), n.referenceCount <= 0 && delete e[t];
      }
  }
  static clearAll() {
    this._assets = null;
  }
  assets = null;
  loadAssets(e) {
    let t = this;
    (e = typeof e == "string" ? [e] : e), (t.assets = []);
    for (let a = 0; a < e.length; a++) {
      let l = e[a],
        c = UrlUtil.splitURLs(l);
      for (let h = 0; h < c.length; h++) {
        let p = new AssetItem(c[h], t);
        AssetsLoader.asset(p.uri) == null
          ? (EventCenter.addListener(
              p,
              t,
              [Event.LOAD, ProgressEvent.PROGRESS, ErrorEvent.ERROR],
              [t.onAssetLoaded, t.onAssetLoadProgress, t.onAssetLoadError]
            ),
            t.assets.push(p))
          : (this.assets()[p.uri].referenceCount += 1);
      }
    }
    if (t.assets.length <= 0) {
      let d = new Event(t, Event.LOAD);
      EventCenter.dispatchEvent(d);
    } else t.multipleThreadLoad();
  }
  _threadsCount = 0;
  threadsCount() {
    let e = this,
      t = e._threadsCount;
    if (isNaN(t) || t < 1) t = AssetsLoader.threadsCount;
    return t;
  }
  loadingItemCount = 0;
  multipleThreadLoad() {
    let e = this;
    if (e.loadingItemCount < e.threadsCount())
      for (let t = 0; t < e.assets.length; t++) {
        let n = e.assets[t];
        if (n.loaded === !1 && n.loading === !1) {
          n.load(), e.loadingItemCount++;
          if (e.loadingItemCount >= e.threadsCount()) break;
        }
      }
  }
  loadProgress() {
    let e = this,
      t = 0,
      n = 0;
    for (let r = 0; r < e.assets.length; r++) {
      let i = e.assets[r];
      (t += i.sliceCount), (n += i.loadPercent() * i.sliceCount);
    }
    return n / t;
  }
  onAssetLoaded(e) {
    let t = this,
      u = e.target;
    EventCenter.removeListener(
      u,
      t,
      [Event.LOAD, ProgressEvent.PROGRESS, ErrorEvent.ERROR],
      [t.onAssetLoaded, t.onAssetLoadProgress, t.onAssetLoadError]
    );
    if (u.type == AssetTypes.AXE)
      for (let l = 0; l < u.assetImages.length; l++) {
        let c = u.assetPaths[l],
          h = u.assetImages[l],
          p = new AssetItem();
        p.assetLoaded(h),
          AssetsLoader.assets()[c] != null && (AssetsLoader.assets()[c].referenceCount += 1),
          (AssetsLoader.assets()[c] = p);
      }
    else
      AssetsLoader.assets()[u.uri] != null &&
        (AssetsLoader.assets()[u.uri].referenceCount += 1),
        (AssetsLoader.assets()[u.uri] = u);
    t.onAssetLoadProgress(), t.loadingItemCount--, t.multipleThreadLoad();
    if (t.loadingItemCount <= 0) {
      let d = new Event(t, Event.LOAD);
      EventCenter.dispatchEvent(d);
    }
  }
  onAssetLoadProgress() {
    let e = this,
      t = e.loadProgress(),
      r = new ProgressEvent(e, t);
    EventCenter.dispatchEvent(r);
  }
  onAssetLoadError(e) {
    let t = this,
      r = e.clone();
    (r.target = t), EventCenter.dispatchEvent(r);
  }
}
